import { reactive, Ref, ref } from 'vue'
import { WidgetError } from 'src/types'
import { Widget } from '@/models'
import useWidgetOperate from './useWidgetOperate'
import useWidgetSort from './useWidgetSort'

/** 控件校验 */
export default function useWidgetValidate(
  widgets: Ref<Widget[]>,
  operate: ReturnType<typeof useWidgetOperate>,
  sorted: ReturnType<typeof useWidgetSort>
) {
  /** 当前标识错误的控件 id */
  const errorWidgetId = ref('')

  /**
   * 标记控件错误，并聚焦
   * @param {string} id 控件 id
   * @param {string} error 错误消息
   */
  function markWidgetError(id: string, error = '') {
    const widget = operate.findWidgetById(id)

    if (!widget) return

    errorWidgetId.value = id

    widget.customError = error

    operate.focusWidget(id)
  }

  return reactive({
    /** 当前标识错误的控件 id */
    errorWidgetId,

    /**
     * 校验控件
     * @param markError 是否聚焦并标记错误控件
     * @param {(widget: Widget) => boolean} filter 控件过滤
     */
    validate(markError = true, filter?: (widget: Widget) => boolean) {
      /** 需要校验的控件 */
      let widgets: Widget[] = sorted.sortedWidgets

      if (filter) widgets = widgets.filter(filter)

      /** 未通过校验的控件 */
      const invalidWidgets = widgets.filter(item => !!item.error)

      const firstInvalid = invalidWidgets[0]

      if (!firstInvalid) return

      if (markError) {
        markWidgetError(firstInvalid.id)
      }

      throw {
        name: 'FaContract:validate',
        message: firstInvalid.error,
        invalidWidgets
      } as WidgetError
    },

    /**
     * 标记控件错误，并聚焦
     * @param {string} id 控件 id
     * @param {string} error 错误消息
     */
    markWidgetError,

    /**
     * 清理控件错误
     * @param {string} [id] 控件 id，未提供则清理所有控件
     */
    clearWidgetError(id?: string) {
      if (id) {
        const widget = operate.findWidgetById(id)
        if (widget) widget.customError = ''
      } else {
        // 清理自定义错误
        widgets.value.forEach(item => (item.customError = ''))
      }
    }
  })
}
